/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.logiclander.ricemine.services.identity;

import com.logiclander.ricemine.utils.LdapUtilities;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.kuali.rice.kim.bo.entity.dto.KimEntityNameInfo;
import org.kuali.rice.kim.util.KimConstants;
import org.springframework.ldap.core.ContextMapper;
import org.springframework.ldap.core.DirContextAdapter;

/**
 *
 * @author tcarroll
 */
public class LdapKimEntityNameInfoMapper implements ContextMapper {

  private final Log log = LogFactory.getLog(getClass());
  private String firstNameAttributeName = null;
  private String middleNameAttributeName = null;
  private String lastNameAttributeName = null;
  private String suffixNameAttributeName = null;
  private String formattedNameAttributeName = null;
  private String titleNameAttributeName = null;
  private String suppressionAttributeName = null;

//beg: methods required by ContextMapper interface
  public Object mapFromContext(Object ctx) {
    validateConfiguration();
    KimEntityNameInfo keni = new KimEntityNameInfo();
    try {
      DirContextAdapter context = (DirContextAdapter) ctx;
      // currently, this assumes that an entity only has one name (the one aligned
      // with this ldap record.  this is a decent assumption for now, but a configurable
      // option for either doing it this way or mapping multiple names would be better
      // perhaps some organizations have multi-valued attributes that list names

      // the entityNameId is a synthetic identifier for the instance of an entity name.
      // this should be unique in the system, but there is no graceful way to do this
      // from an ldap mapping

      keni.setEntityNameId("1");//is there an ldap attribute for this?
      keni.setNameTypeCode("PRFR");//is there an ldap attribute for this?

      keni.setFirstNameUnmasked(LdapUtilities.materialize(context.getStringAttribute(firstNameAttributeName)));
      keni.setMiddleNameUnmasked(LdapUtilities.materialize(context.getStringAttribute(middleNameAttributeName)));
      keni.setLastNameUnmasked(LdapUtilities.materialize(context.getStringAttribute(lastNameAttributeName)));
      keni.setFormattedNameUnmasked(LdapUtilities.materialize(context.getStringAttribute(formattedNameAttributeName)));
      keni.setSuffixUnmasked(LdapUtilities.materialize(context.getStringAttribute(suffixNameAttributeName)));
      keni.setTitleUnmasked(LdapUtilities.materialize(context.getStringAttribute(titleNameAttributeName)));

      String suppressionAttributeValue = context.getStringAttribute(suppressionAttributeName);
      if (suppressionAttributeValue != null && suppressionAttributeValue.equalsIgnoreCase("TRUE")) {
        keni.setSuppressName(true);
        keni.setFirstName(KimConstants.RESTRICTED_DATA_MASK);
        keni.setMiddleName(KimConstants.RESTRICTED_DATA_MASK);
        keni.setLastName(KimConstants.RESTRICTED_DATA_MASK);
        keni.setFormattedName(KimConstants.RESTRICTED_DATA_MASK);
        keni.setSuffix(KimConstants.RESTRICTED_DATA_MASK);
        keni.setTitle(KimConstants.RESTRICTED_DATA_MASK);
      } else {
        keni.setSuppressName(false);
        keni.setFirstName(LdapUtilities.materialize(context.getStringAttribute(firstNameAttributeName)));
        keni.setMiddleName(LdapUtilities.materialize(context.getStringAttribute(middleNameAttributeName)));
        keni.setLastName(LdapUtilities.materialize(context.getStringAttribute(lastNameAttributeName)));
        keni.setFormattedName(LdapUtilities.materialize(context.getStringAttribute(formattedNameAttributeName)));
        keni.setSuffix(LdapUtilities.materialize(context.getStringAttribute(suffixNameAttributeName)));
        keni.setTitle(LdapUtilities.materialize(context.getStringAttribute(titleNameAttributeName)));
      }
      keni.setActive(true);//is there an ldap attribute for this?
      keni.setDefault(true);//is there an ldap attribute for this?
    } catch (Throwable t) {
      log.error("Error in ContextMapper", t);
      String msg = "ContextMapper failed to create a LdapRecord from the specified Context: " + ctx;
      throw new RuntimeException(msg, t);
    }
    if (log.isDebugEnabled()) {
      log.debug("mapped LdapKimEntityName:"
              + "(entityNameId=" + keni.getEntityNameId() + ")"
              + "(nameTypeCode=" + keni.getNameTypeCode() + ")"
              + "(isActive=" + keni.isActive() + ")"
              + "(isDefault=" + keni.isDefault() + ")"
              + "(firstName=" + keni.getFirstName() + ")"
              + "(middleName=" + keni.getMiddleName() + ")"
              + "(lastName=" + keni.getLastName() + ")"
              + "(formattedName=" + keni.getFormattedName() + ")"
              + "(suffix=" + keni.getSuffix() + ")"
              + "(title=" + keni.getTitle() + ")"
              + "(isSuppressedName=" + keni.isSuppressName() + ")");
    }
    return keni;
  }

//end: methods required by ContextMapper interface
//beg: helper methods
  public String getFirstNameAttributeName() {
    return this.firstNameAttributeName;
  }

  public void setFirstNameAttributeName(String attrName) {
    this.firstNameAttributeName = attrName;
  }

  public String getMiddleNameAttributeName() {
    return this.middleNameAttributeName;
  }

  public void setMiddleNameAttributeName(String attrName) {
    this.middleNameAttributeName = attrName;
  }

  public String getLastNameAttributeName() {
    return this.lastNameAttributeName;
  }

  public void setLastNameAttributeName(String attrName) {
    this.lastNameAttributeName = attrName;
  }

  public String getSuffixNameAttributeName() {
    return this.suffixNameAttributeName;
  }

  public void setSuffixNameAttributeName(String attrName) {
    this.suffixNameAttributeName = attrName;
  }

  public String getFormattedNameAttributeName() {
    return this.formattedNameAttributeName;
  }

  public void setFormattedNameAttributeName(String attrName) {
    this.formattedNameAttributeName = attrName;
  }

  public String getTitleNameAttributeName() {
    return this.titleNameAttributeName;
  }

  public void setTitleNameAttributeName(String attrName) {
    this.titleNameAttributeName = attrName;
  }

  public String getSuppressionAttributeName() {
    return this.suppressionAttributeName;
  }

  public void setSuppressionAttributeName(String attrName) {
    this.suppressionAttributeName = attrName;
  }

  private void validateConfiguration() {
    if (firstNameAttributeName == null) {
      String msg = "The property 'firstNameAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (middleNameAttributeName == null) {
      String msg = "The property 'middleNameAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (lastNameAttributeName == null) {
      String msg = "The property 'lastNameAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (suffixNameAttributeName == null) {
      String msg = "The property 'suffixNameAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (formattedNameAttributeName == null) {
      String msg = "The property 'formattedNameAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (titleNameAttributeName == null) {
      String msg = "The property 'titleNameAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
    if (suppressionAttributeName == null) {
      String msg = "The property 'suppressionAttributeName' must be set.";
      throw new IllegalStateException(msg);
    }
  }
//end: helper methods
}
